5 'require tools.widgets as widgets';
6 'require strongswan_algorithms';
8 function addAlgorithms(o, algorithms) {
9 algorithms.forEach(function (algorithm) {
10 if (strongswan_algorithms.isInsecure(algorithm)) {
11 o.value(algorithm, '%s*'.format(algorithm));
22 m = new form.Map('ipsec', _('strongSwan Configuration'),
23 _('Configure strongSwan for secure VPN connections.'));
26 // strongSwan General Settings
27 s = m.section(form.TypedSection, 'ipsec', _('General Settings'));
30 o = s.option(widgets.ZoneSelect, 'zone', _('Zone'),
31 _('Firewall zone that has to match the defined firewall zone'));
35 o = s.option(widgets.NetworkSelect, 'listen', _('Listening Interfaces'),
36 _('Interfaces that accept VPN traffic'));
37 o.datatype = 'interface';
38 o.placeholder = _('Select an interface or leave empty for all interfaces');
43 o = s.option(form.Value, 'debug', _('Debug Level'),
44 _('Trace level: 0 is least verbose, 4 is most'));
46 o.datatype = 'range(0,4)';
48 // Remote Configuration
49 s = m.section(form.GridSection, 'remote', _('Remote Configuration'),
50 _('Define Remote IKE Configurations.'));
52 s.nodescriptions = true;
54 o = s.option(form.Flag, 'enabled', _('Enabled'),
55 _('Configuration is enabled or not'));
58 o = s.option(form.Value, 'gateway', _('Gateway (Remote Endpoint)'),
59 _('IP address or FQDN name of the tunnel remote endpoint'));
60 o.datatype = 'or(hostname,ipaddr)';
63 o = s.option(form.Value, 'local_gateway', _('Local Gateway'),
64 _('IP address or FQDN of the tunnel local endpoint'));
65 o.datatype = 'or(hostname,ipaddr)';
68 o = s.option(form.Value, 'local_sourceip', _('Local Source IP'),
69 _('Virtual IP(s) to request in IKEv2 configuration payloads requests'));
70 o.datatype = 'ipaddr';
73 o = s.option(form.Value, 'local_ip', _('Local IP'),
74 _('Local address(es) to use in IKE negotiation'));
75 o.datatype = 'ipaddr';
78 o = s.option(form.Value, 'local_identifier', _('Local Identifier'),
79 _('Local identifier for IKE (phase 1)'));
80 o.datatype = 'string';
81 o.placeholder = 'C=US, O=Acme Corporation, CN=headquarters';
84 o = s.option(form.Value, 'remote_identifier', _('Remote Identifier'),
85 _('Remote identifier for IKE (phase 1)'));
86 o.datatype = 'string';
87 o.placeholder = 'C=US, O=Acme Corporation, CN=soho';
90 o = s.option(form.ListValue, 'authentication_method',
91 _('Authentication Method'), _('IKE authentication (phase 1)'));
93 o.value('psk', 'Pre-shared Key');
94 o.value('pubkey', 'Public Key');
96 o = s.option(form.Value, 'pre_shared_key', _('Pre-Shared Key'),
97 _('The pre-shared key for the tunnel'));
98 o.datatype = 'string';
101 o.depends('authentication_method', 'psk');
103 o = s.option(form.Flag, 'mobike', _('MOBIKE'),
104 _('MOBIKE (IKEv2 Mobility and Multihoming Protocol)'));
108 o = s.option(form.ListValue, 'fragmentation', _('IKE Fragmentation'),
109 _('Use IKE fragmentation'));
117 o = s.option(form.MultiValue, 'crypto_proposal', _('Crypto Proposal'),
118 _('List of IKE (phase 1) proposals to use for authentication'));
119 o.load = function (section_id) {
123 var sections = uci.sections('ipsec', 'crypto_proposal');
124 if (sections.length == 0) {
125 this.value('', _('Please create a Proposal first'));
127 sections.forEach(L.bind(function (section) {
128 if (section.is_esp != '1') {
129 this.value(section['.name']);
134 return this.super('load', [section_id]);
138 o = s.option(form.MultiValue, 'tunnel', _('Tunnel'),
139 _('Name of ESP (phase 2) section'));
140 o.load = function (section_id) {
144 var sections = uci.sections('ipsec', 'tunnel');
145 if (sections.length == 0) {
146 this.value('', _('Please create a Tunnel first'));
148 sections.forEach(L.bind(function (section) {
149 this.value(section['.name']);
153 return this.super('load', [section_id]);
157 // Tunnel Configuration
158 s = m.section(form.GridSection, 'tunnel', _('Tunnel Configuration'),
159 _('Define Connection Children to be used as Tunnels in Remote Configurations.'));
161 s.nodescriptions = true;
163 o = s.option(form.DynamicList, 'local_subnet', _('Local Subnet'),
164 _('Local network(s)'));
165 o.datatype = 'subnet';
166 o.placeholder = '192.168.1.1/24';
169 o = s.option(form.DynamicList, 'remote_subnet', _('Remote Subnet'),
170 _('Remote network(s)'));
171 o.datatype = 'subnet';
172 o.placeholder = '192.168.2.1/24';
175 o = s.option(form.Value, 'local_nat', _('Local NAT'),
176 _('NAT range for tunnels with overlapping IP addresses'));
177 o.datatype = 'subnet';
180 o = s.option(form.MultiValue, 'crypto_proposal',
181 _('Crypto Proposal (Phase 2)'),
182 _('List of ESP (phase two) proposals. Only Proposals with checked ESP flag are selectable'));
183 o.load = function (section_id) {
187 var sections = uci.sections('ipsec', 'crypto_proposal');
188 if (sections.length == 0) {
189 this.value('', _('Please create an ESP Proposal first'));
191 sections.forEach(L.bind(function (section) {
192 if (section.is_esp == '1') {
193 this.value(section['.name']);
198 return this.super('load', [section_id]);
202 o = s.option(form.ListValue, 'startaction', _('Start Action'),
203 _('Action on initial configuration load'));
210 o = s.option(form.Value, 'updown', _('Up/Down Script Path'),
211 _('Path to script to run on CHILD_SA up/down events'));
216 s = m.section(form.GridSection, 'crypto_proposal',
217 _('Encryption Proposals'),
218 _('Configure Cipher Suites to define IKE (Phase 1) or ESP (Phase 2) Proposals.'));
220 s.nodescriptions = true;
222 o = s.option(form.Flag, 'is_esp', _('ESP Proposal'),
223 _('Whether this is an ESP (phase 2) proposal or not'));
225 o = s.option(form.ListValue, 'encryption_algorithm',
226 _('Encryption Algorithm'),
227 _('Algorithms marked with * are considered insecure'));
228 o.default = 'aes256gcm128';
229 addAlgorithms(o, strongswan_algorithms.getEncryptionAlgorithms());
230 addAlgorithms(o, strongswan_algorithms.getAuthenticatedEncryptionAlgorithms());
233 o = s.option(form.ListValue, 'hash_algorithm', _('Hash Algorithm'),
234 _('Algorithms marked with * are considered insecure'));
235 strongswan_algorithms.getEncryptionAlgorithms().forEach(function (algorithm) {
236 o.depends('encryption_algorithm', algorithm);
238 o.default = 'sha512';
240 addAlgorithms(o, strongswan_algorithms.getHashAlgorithms());
242 o = s.option(form.ListValue, 'dh_group', _('Diffie-Hellman Group'),
243 _('Algorithms marked with * are considered insecure'));
244 o.default = 'modp3072';
245 addAlgorithms(o, strongswan_algorithms.getDiffieHellmanAlgorithms());
247 o = s.option(form.ListValue, 'prf_algorithm', _('PRF Algorithm'),
248 _('Algorithms marked with * are considered insecure'));
249 o.validate = function (section_id, value) {
250 var encryptionAlgorithm = this.section.formvalue(section_id, 'encryption_algorithm');
252 if (strongswan_algorithms.getAuthenticatedEncryptionAlgorithms().includes(
253 encryptionAlgorithm) && !value) {
254 return _('PRF Algorithm must be configured when using an Authenticated Encryption Algorithm');
260 o.depends('is_esp', '0');
261 addAlgorithms(o, strongswan_algorithms.getPrfAlgorithms());